﻿// <copyright file="GameEvent.cs" company="ALCPU">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <author>Arthur Liberman</author>
// <email>Arthur_Liberman@hotmail.com</email>
// <date>04-01-2010</date>
// <summary>Contains basic piece definition.</summary>

namespace ChessDefinitions
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ChessDefinitions;

    /// <summary>
    /// Represents the method that will have piece events in Chess.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="gea">A <see cref="Chess.GameEventArgs"/> that contains data about the event.</param>
    public delegate void PieceEvent(IPiece sender, GameEventArgs<IPiece> gea);

    /// <summary>
    /// Represents the method that will have player events in Chess.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="gea">A <see cref="Chess.GameEventArgs"/> that contains data about the event.</param>
    public delegate void PlayerEvent(PlayerBase sender, GameEventArgs<PlayerBase> gea);

    /// <summary>
    /// Describes possible game events that may occur during a game.
    /// </summary>
    public enum GameEventType
    {
        /// <summary>
        /// No event occured.
        /// </summary>
        None,

        /// <summary>
        /// No legal moves remain.
        /// </summary>
        NoLegalMoves,

        /// <summary>
        /// When the player's piece moves.
        /// </summary>
        Move,

        /// <summary>
        /// When the player's piece attacks.
        /// </summary>
        Attack,

        /// <summary>
        /// When a player is in a Check.
        /// </summary>
        Check,

        /// <summary>
        /// When a player is in a Checkmate.
        /// </summary>
        Checkmate,

        /// <summary>
        /// When a player is in a Stalemate.
        /// </summary>
        Stalemate,

        /// <summary>
        /// When a checkers piece gets Crowned.
        /// </summary>
        Crowned,

        /// <summary>
        /// When a game times out.
        /// </summary>
        Timeout,

        /// <summary>
        /// When a player has finished his turn in the game.
        /// </summary>
        TurnEnded
    }

    /// <summary>
    /// Game event arguments class
    /// </summary>
    /// <typeparam name="T">The sender class</typeparam>
    public class GameEventArgs<T> : EventArgs where T : class
    {
        /// <summary>
        /// Figure which caused the event.
        /// </summary>
        private T sender;

        /// <summary>
        /// Describes the game event which occured.
        /// </summary>
        private GameEventType gameEventType;

        /// <summary>
        /// Initializes a new instance of the <see cref="GameEventArgs&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="sender">The piece which caused the event to be risen.</param>
        /// <param name="eventType">Type of the event.</param>
        public GameEventArgs(T sender, GameEventType eventType)
        {
            this.sender = sender;
            this.gameEventType = eventType;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GameEventArgs&lt;T&gt;"/> class.
        /// </summary>
        public GameEventArgs()
        {
            this.sender = null;
            this.gameEventType = GameEventType.None;
        }

        /// <summary>
        /// Gets the piece which caused the event to rise.
        /// </summary>
        /// <value>The piece.</value>
        public T Sender
        {
            get { return this.sender; }
        }

        /// <summary>
        /// Gets the type of the game event.
        /// </summary>
        /// <value>The type of the game event.</value>
        public GameEventType GameEventType
        {
            get { return this.gameEventType; }
        }
    }
}
